<?php
/**
 * Controller to manage modules/controllers/actions to be able to generate ACL resorces 
 * for access permissions validation. Modules/controllers/action are stored in tree structure.
 * 
 * @author Konstantin Shamko <konstantin.shamko@gmail.com> 
 * @version 0.0.1
 * @copyright  Copyright (c) 2009 Konstantin Shamko
 * @category VaselinEngine
 * @package Usermanagement Module
 * @subpackage Controller
 * @license  New BSD License
 *
 */
class admin_ModulesController extends Bel_Controller_Tree {
	
	
	/**
	 * Modules Model
	 *
	 * @var Models_Usermanagement_Modules
	 */
	protected $_tree;
	
	/**
	 * Initialization
	 *
	 */
	public function init() {
		$this->_tree = new Models_Usermanagement_Modules ( );
		$this->_tree_template = 'usermanagement/modules/modules_tree.tpl';
		$this->_formname = 'modules_form';
		$this->_move_form_template = 'usermanagement/modules/move_node.tpl';		
		$this->_formdata = new Zend_Session_Namespace ( 'formdata' );		
		
		if(!in_array($this->_request->getActionName(),array('index','addform','editform','moveform'))){
			Helpers_Usermanagement_Cache::clearAclCache();
		}
		
		parent::init ();
	}
	
	/**
	 * Displays added modules-controllers-actions.
	 * Displays tree of modules-controllers-actions found automatically
	 *
	 */
	public function indexAction(){
		$this->_parseForModules();
		parent::indexAction();
	}
	
	/**
	 * Adds entry to modules table. Checks if module name is unique
	 *
	 */
	public function addnodeAction(){		
		$module = $this->_tree->getModuleByName($this->_request->getParam('module_name'));
		
		if($module){
			$this->_messages->setMessage('Entry with such name already exists','error');
			$this->_redirect($this->_default_action);
		}
		
		parent::addnodeAction();
	}

	/**
	 * Updates entry in modules table. Checks if module name is unique
	 *
	 */
	public function editnodeAction(){		
		$module = $this->_tree->getModuleByName($this->_request->getParam('module_name'));
		
		if($module && $module[0]->module_id!=$this->_request->getParam('module_id')){
			$this->_messages->setMessage('Entry with such name alredy exists','error');
			$this->_redirect($this->_default_action);
		}
		parent::editnodeAction();
	}
	
	/**
	 * Reads application dir to find modules-controlles-actions automatically
	 *
	 */	
	private function _parseForModules(){
		$path_to_controllers = HOME_DIR.'app/controllers/';
		
		$mod_dir = dir($path_to_controllers);
		$r = array();
		
		$module_index = 0;
    	while (false !== ($module = $mod_dir->read())) {
    		if($module!=='..' && $module!=='.' && $module!=='.svn'){
   				$contr_dir = dir($path_to_controllers.$module);
   				
   				
   				$module_db = $this->_tree->getModuleByName($module);
   				if($module_db){
   					$module_branch = $this->_tree->getTreeBranch($module_db[0]->module_id);	
   				}
   				
   				$r['module'][$module_index]['name'] = $module;
   				$r['module'][$module_index]['added'] = ($module_db)?$module_db[0]->module_id:false;
   				   				
   				$controller_index = 0;
   				while (false !== ($contr = $contr_dir->read())) {
   					if($contr!=='..' && $contr!=='.' && $contr!=='.svn'){
   						$controller_name = strtolower(str_replace('Controller.php','',$contr));
   						$controller_added = false;
   						
   						
   						if($module_db && $module_branch){
   							foreach ($module_branch as $_m){
   								if($_m->module_level==3){
   									if($_m->module_name==$controller_name){
   										$controller_added = $_m->module_id;
   										$controller_left = $_m->module_left_key;
   										break;
   									}
   								}
   							}
   						}
   						
   						$r['module'][$module_index]['controller'][$controller_index]['name'] = $controller_name;
   						$r['module'][$module_index]['controller'][$controller_index]['added'] = $controller_added;
   						
   						$class_name = ($module=='default')?str_replace('.php','',$contr):$module.'_'.str_replace('.php','',$contr); 
   						
   						include_once $path_to_controllers.$module.'/'.$contr;
   						$actions = get_class_methods($class_name);//new $class_name);
   						
   						$action_index = 0;
   						foreach ($actions as $action){
							if($pos = strpos($action,'Action')){
								$module_name = substr($action,0,$pos);
								$module_added = false;
								
								if($module_db && $module_branch && $controller_added){
		   							foreach ($module_branch as $_m){
		   								if($_m->module_level==4 && $controller_left<$_m->module_left_key){
		   									
		   									//echo $controller_name." ".$controller_left." ".$_m->module_name." ".$_m->module_left_key." ".$_m->module_right_key."<br/>";
		   									
		   									if($_m->module_name==$module_name){
		   										$module_added = $_m->module_id;
		   										break;
		   									}
		   								}
		   							}									
								}
								
								$r['module'][$module_index]['controller'][$controller_index]['action'][$action_index]['name']=$module_name;
								$r['module'][$module_index]['controller'][$controller_index]['action'][$action_index]['added']=$module_added;
								$action_index++;
							}
   						}

   						$controller_index++;
   					}
   				}
   				$contr_dir->close();
   				$module_index++;
   			}			
		}		
		$mod_dir->close();

		$root_node = $this->_tree->getTree('module_level=1');
		$this->view->assign('root_node_id', $root_node[0]->module_id);
		$this->view->assign('scanned_modules',$r);
	}
}